Use spawn() instead of open3 and avoid use of Dir.chdir

Changing the current directory affects the whole process, so without
eliminating the use of Dir.chdir we cannot safely run threaded workers
or dry-run agents on a threaded rack application server, etc.

Akinori MUSHA 9 years ago
parent
commit
b93e04b36c
1 changed files with 18 additions and 18 deletions
  1. 18 18
      app/models/agents/shell_command_agent.rb

+ 18 - 18
app/models/agents/shell_command_agent.rb

@@ -1,5 +1,3 @@
1
-require 'open3'
2
-
3 1
 module Agents
4 2
   class ShellCommandAgent < Agent
5 3
     default_schedule "never"
@@ -88,23 +86,25 @@ module Agents
88 86
     end
89 87
 
90 88
     def run_command(path, command)
91
-      result = nil
92
-      errors = nil
93
-      exit_status = nil
94
-
95
-      Dir.chdir(path){
96
-        begin
97
-          stdin, stdout, stderr, wait_thr = Open3.popen3(command)
98
-          exit_status = wait_thr.value.to_i
99
-          result = stdout.gets(nil)
100
-          errors = stderr.gets(nil)
101
-        rescue Exception => e
102
-          errors = e.to_s
103
-        end
104
-      }
89
+      begin
90
+        rout, wout = IO.pipe
91
+        rerr, werr = IO.pipe
92
+
93
+        pid = spawn(command, chdir: path, out: wout, err: werr)
105 94
 
106
-      result = result.to_s.strip
107
-      errors = errors.to_s.strip
95
+        wout.close
96
+        werr.close
97
+
98
+        (result = rout.read).strip!
99
+        (errors = rerr.read).strip!
100
+
101
+        _, status = Process.wait2(pid)
102
+        exit_status = status.exitstatus
103
+      rescue Exception => e
104
+        errors = e.to_s
105
+        result = ''.freeze
106
+        exit_status = nil
107
+      end
108 108
 
109 109
       [result, errors, exit_status]
110 110
     end